DR. HAX COLUMN If you have an application thats copy protected, or which has a registration or expiration scheme, its probably easier to fix than you think. All you need is some knowledge of Macintosh programming, a debugger such as MacsBug 6.1, and the willingness to roll up your sleeves and see what you can do. Before you start working on an application, be sure to make a copy of it. Well be making some low-level changes to the code, and its easy to permanently damage something.First lets examine how an application detects that it has expired. Normally theres a piece of code that goes something like this: move the current time into a memory address move the expiration date into another address compare the two addresses if the time is greater, quit - else continue. For registration, it might go something like this: get the serial number from the user perform some arithmetic operations on the serial number move the result into an address check if the result is zero if it isnt, quit - else record the registration. Heres an example for copy protection: change the floppy disk motor speed get the contents of disk sector XXX perform some hefty arithmetic on the contents move the result into an address check if the result is 312 if it isnt, quit - else continue. You'll probably notice that all three of these examples have something in common - no matter how complicated the initial scheme, they all compare numbers to see if the desired conditions are met. If we concentrate on changing the comparison code, we can break any of these schemes.Well use MacsBug to discover where the code actually is. The first thing you need is a reference point: pick a Macintosh toolbox call that occurs right after the checking code has failed. For example, if the program beeps if it has expired, you can use Sysbeep. If it puts up an alert box, you can use Alert (or perhaps StopAlert). Use MacsBugs "ATB" command to drop into the debugger when this toolbox call occurs. For example, "ATB sysbeep" will stop the computer right before it beeps. Then you can dissassemble the code (working backwards) to discover an assembly command that compares the numbers - such as "TST.L" or "CMP.B". The "IP" command is useful for this; you may have to play with MacsBug for a few hours to see what each assembly language instruction does (dont worry if you dont know much about assembly; I learned everything I know from watching MacsBug steps through instructions).When you find the specific set of instructions, there are two possibilities: the first is that the program branches to the bad code and executes the good code if it doesnt branch. This might look something like this (some MacsBug junk removed for clarity): +016C TST.L D1 | 4A81+016E BEQ.S *+$000E | 670C+0170 *** GOOD CODE HERE*** +017C BRA.S *+$002C | 602A+017E *** BAD CODE HERE! *** This is the easiest type of code to fix. All we need to do is replace the "TST.L" and "BEQ.S" instructions with something that will just drop through to the next instruction at +0170. The perfect thing to replace it with is two "NOP" instructions ("4E71" in machine language), which does nothing at all except go to the next instruction. See the machine code on the right (4A81, 670C, etc.)? If you open up a code resource in ResEdit, thats what the numbers are. Simply write down a few of them around the instruction you need to change, perhaps: "4A81 670C 4EBA FCB8 2200" (you get the extra numbers from further on in MacsBug). Be sure to write down quite a few of them and not just a couple, because theres likely to be a lot of values that are the same in any file, and you might change the wrong one by mistake. Search each and every code resource that you find in ResEdit for the string "4A81670C4EBAFCB82200" (there are no spaces in ResEdit). In this case, when you find it, youll change the characters "4A81670C" to "4E714E71". Provided you changed it in the correct place, the program can now never branch to the bad code.The other possibility is that the branch instruction goes to the good code, so you need to make the program branch every time: +016C TST.L D1 | 4A81+016E BEQ.S *+$000E | 670C+0170 *** BAD CODE HERE! *** +017C BRA.S *+$002C | 602A+017E *** GOOD CODE HERE *** In this case, you need to replace the "TST.L" and "BEQ.S"instructions with code that makes the program branch every time. The first instruction should be "6000" (BRA), and the second should be the distance to branch. You can get this from the original instruction in this line: the "BEQ.S *+$000E". The "000E" is what you want. So, using ResEdit, change the "4A81670C" to "6000000E". Once again, be sure to use a few extra characters when you search.So thats the essence of simple code cracking. As you get better at it, youll be able to fix things that are a little tougher than the examples shown here. Just remember that it doesnt have to be complicated - you dont have to break someones complicated encryption scheme, you just have to use a little knowledge of how your computer works to find the weak spot.